import { ZegoExpressEngine } from "zego-express-engine-webrtc"


export async function getToken(userInfo, tokenUrl) {
  const res = await uni.request({
    url: tokenUrl,
    method: "get",
    data: {
      app_id: userInfo.appID,
      id_name: userInfo.userID
    }
  })

  return res[1].data
}

export class Express {
  appID = 1739272706 
  server = "wss://wssliveroom-test.zego.im/ws"
  tokenURL = "https://wsliveroom-alpha.zego.im:8282/token"
  roomID
  userID = "web" + Date.now()
  userName = "nick" + Date.now()
  streamID = "webrtc" + Date.now() // 本地流ID

  secondStreamID = null // 用于存放自定义存储的流，比如屏幕共享
  secondStream = null // 用于存放自定义存储的流，比如屏幕共享
  roomUserList = [] // 房间用户列表
  zegoEngine
  token
  localStream  // 本地流
  remoteStreams = [] // 远程流列表
  remoteStreamInfos = [] // 远程流ID
  hasLogin = false
  mixerOutputList = []

  constructor() {
  }

  init() {
    this.initSDK()
    this.zgOnListener()
  }


  async initSDK() {
    try {
      this.zegoEngine = new ZegoExpressEngine(this.appID, this.server)
      this.zegoEngine.setDebugVerbose(false)
      // this.zegoEngine.setLogConfig({ logLevel: "warn" })
    } catch (error) {
      console.error("error in initsdk", error)
    }
  }

  async login(roomID) {
    try {
      this.roomID = roomID
      this.token = await getToken({ userID: this.userID, appID: this.appID }, this.tokenURL)
      let isLogin = await this.zegoEngine.loginRoom(
        roomID,
        this.token,
        {
          userID: this.userID,
          userName: this.userName
        },
        {
          userUpdate: true
        }
      )
      this.hasLogin = isLogin
      console.log("mytag isLogin", isLogin)
    } catch (error) {
      console.log("mytag error", error);
    }
  }

  async logout() {
    try {
      // 停止推流
      this.localStream && this.zegoEngine.stopPublishingStream(this.streamID)
      // 销毁画面
      this.localStream && this.zegoEngine.destroyStream(this.localStream)

      this.remoteStreams.forEach((element) => {
        this.zegoEngine.stopPlayingStream(element.id) // 停止拉流
      })
      this.remoteStreams = []
      this.zegoEngine.logoutRoom(this.roomID)
    } catch (error) {
      console.log("mytag logout error", error);
    }
  }

  async enumDevices() {
    const devices = await this.zegoEngine.enumDevices()
    return devices
  }

  async checkSystemRequirements() {
    const result = await this.zegoEngine.checkSystemRequirements()
    if (!result.webRTC) {
      alert("当前环境不支持webRTC 检查下环境试试吧")
    } else if (!result.camera) {
      alert("当前浏览器不支持获取摄像头设备")
    } else if (!result.microphone) {
      alert("当前浏览器不支持获取麦克风设备")
    } else if (!result.videoCodec.H264) {
      alert("当前浏览器不支持H264视频编码")
    } else if (!result.videoCodec.VP8) {
      alert("当前浏览器不支持VP8视频编码")
    } else if (!result.customCapture) {
      alert("当前浏览器不支持第三方")
    }
    return true
  }

  async createStream(createOption, publisOption) {
    try {
      const config = {
        camera: { camera: { video: true, audio: true, videoQuality: 4, frameRate: 11, bitrate: 300, width: 320, height: 320 } },
        screen: { screen: { audio: false } },
      }
      console.log("mytag createOption", createOption);
      this.localStream = await this.zegoEngine.createStream(createOption ? createOption : config.camera)
      this.zegoEngine.startPublishingStream(this.streamID, this.localStream, publisOption)
      return this.localStream
    } catch (error) {
      console.log("mytag error", error);
    }
  }

  async createSecondStream(createOption, publisOption) {
    try {
      const config = {
        camera: { camera: { video: true, audio: true, videoQuality: 4, frameRate: 11, bitrate: 300, width: 320, height: 320 } },
        screen: { screen: { audio: false } },
      }
      this.secondStreamID = "webrtc" + Date.now() + "_2"
      this.secondStream = await this.zegoEngine.createStream(createOption ? createOption : config.camera)
      this.zegoEngine.startPublishingStream(this.secondStreamID, this.secondStream, publisOption)
      return this.secondStream
    } catch (error) {
      console.log("mytag error", error);
    }
  }


  async getPlayStream(streamItem) {
    let remoteStream = await this.zegoEngine.startPlayingStream(streamItem.streamID, { videoCodec: "H264" })
    this.remoteStreamInfos.push(streamItem)
    this.remoteStreams.push(remoteStream)

    // console.log("mytag express this.remoteStreams", this.remoteStreams)
  }

  async mixStream() {
    try {
      const taskID = 'task-' + new Date().getTime();
      const mixStreamID = 'mixwebrtc-' + new Date().getTime();
      const inputList = []
      if (this.localStream) {
        inputList.push({
          streamID: this.streamID,
          contentType: 1,
          layout: {
            top: 0,
            left: 0,
            bottom: 240,
            right: 320
          }
        })
      }

      if (this.remoteStreamInfos.length) {
        inputList.push({
          streamID: this.remoteStreamInfos[0].streamID,
          contentType: 1,
          layout: {
            top: 250,
            left: 250,
            bottom: 500,
            right: 500
          }
        })
      }
      if (this.secondStreamID && this.secondStream) {
        inputList.push({
          streamID: this.secondStreamID,
          layout: {
            top: 0,
            left: 300,
            bottom: 240,
            right: 320
          }
        })
      }
      const outputList = [mixStreamID]
      const res = await this.zegoEngine.startMixerTask({
        taskID,
        inputList,
        outputList,
        outputConfig: {
          outputBitrate: 300,
          outputFPS: 30,
          outputWidth: 500,
          outputHeight: 500,
          outputAudioChannels: 2
        }
      })
      if (res.errorCode === 0) {
        this.mixerOutputList = JSON.parse(res.extendedData).mixerOutputList
        // console.log("mytag this.mixerOutputList", this.mixerOutputList);
        return this.mixerOutputList[0]
      } else {
        const res = JSON.parse(res.extendedData)
        console.log("mytag res", res);
      }

    } catch (error) {
      console.log("mytag error", error);
    }
  }

  // async mixAudioStream(){

  // }

  zgOffListener() {
    for (const key in this.listener) {
      if (Object.hasOwnProperty.call(this.listener, key)) {
        // @ts-expect-error
        this.zegoEngine.off(key, this.listener[key])
      }
    }
  }

  zgOnListener() {
    for (const key in this.listener) {
      if (Object.hasOwnProperty.call(this.listener, key)) {
        // @ts-expect-error
        this.zegoEngine.on(key, this.listener[key].bind(this))
      }
    }
  }

  listener = {
    // RTC *******************
    // 推流质量回调
    publishQualityUpdate() {
      // console.log("mytag listen publishQualityUpdate 推流质量回调", arguments)
    },

    playQualityUpdate() {
      console.log("mytag listen playQualityUpdate 拉流质量回调", arguments)
    },
    // 推流状态回调
    publisherStateUpdate() {
      console.log("mytag listen publisherStateUpdate 推流状态回调", arguments)
    },
    // 房间内流变化回调
    roomStreamUpdate(roomID, updateType, streamList) {
      console.log("mytag roomStreamUpdate 房间内流变化回调", arguments)
      if (updateType === "ADD") {
        streamList.forEach((element) => {
          this.getPlayStream(element)
        })
      }
    },

    // 接收对端设置的流附加信息
    streamExtraInfoUpdate() {
      console.log("mytag listen streamExtraInfoUpdate", arguments)
    },
    //  拉流状态回调
    playerStateUpdate() {
      console.log("mytag listen playerStateUpdate", arguments)
    },

    // RTM ******************* 事件监听
    // 当房间用户发生变化时触发
    roomUserUpdate(roomID, updateType, userList) {
      try {
        console.log("mytag roomUserUpdate", roomID, updateType, userList)
        console.log("mytag this.userID", this.userID)
        if (updateType === "ADD") {
          userList
            .filter((item) => item.userID !== this.userID)
            .forEach((item) => {
              this.roomUserList.push(item)
            })
        } else if (updateType === "DELETE") {
          userList.forEach((user) => {
            const i = this.roomUserList.findIndex((item) => item.userID === user.userID)
            this.roomUserList.splice(i, 1)
          })
        }
      } catch (error) {
        console.error("error roomUserUpdate", error)
      }
    },
    // 房间和服务器之间的连接状态发生变化时触发
    roomStateUpdate() {
      console.log("mytag listen roomStateUpdate", arguments)
    },
    // 房间内人数发生改变时触发
    roomOnlineUserCountUpdate() {
      console.log("mytag listen roomOnlineUserCountUpdate", arguments)
    },
    // 房间广播消息通知
    IMRecvBroadcastMessage() {
      console.log("mytag listen IMRecvBroadcastMessage", arguments)
    },
    // 房间弹幕消息通知
    IMRecvBarrageMessage() {
      console.log("mytag listen IMRecvBarrageMessage", arguments)
    },
    // 监听自定义信令通知
    IMRecvCustomCommand() {
      console.log("mytag listen IMRecvCustomCommand", arguments)
    },
    // 监听房间附加消息通知
    roomExtraInfoUpdate() {
      console.log("mytag listen roomExtraInfoUpdate", arguments)
    }
  }
}

